﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using FBroSharp;                 // ⚠️ #1 MOST CRITICAL! FBroSharpControl, FBroSharpBrowserListControl - ALWAYS FIRST!
using FBroSharp.Const;           // ⚠️ REQUIRED! FBroSharpTransitionType, FBroSharpWindowOpenDisposition
using FBroSharp.DataType;        // ⚠️ REQUIRED! FBroSharpEventDisableControl (struct!)
using FBroSharp.Event;           // ⚠️ REQUIRED! FBroSharpBrowserEvent, FBroInitEvent
using FBroSharp.Lib;             // ⚠️ CRITICAL! IFBroSharpBrowser, IFBroSharpFrame, IFBroSharpUseExtraData
using FBroSharp.Value;           // ⚠️ CRITICAL! IFBroSharpDictionaryValue, FBroSharpWindowsInfo, FBroSharpBrowserSetting
using FBroSharp.Callback;        // ⚠️ REQUIRED! Callback function types

namespace 多线程注册脚本
{
    public partial class Form1 : Form
    {
        // 多线程管理
        private List<RegistrationTask> _registrationTasks = new List<RegistrationTask>();
        private CancellationTokenSource _cancellationTokenSource;
        private int _completedCount = 0;
        private int _successCount = 0;
        private int _failedCount = 0;

        // 注册数据
        private List<RegistrationData> _registrationDataList = new List<RegistrationData>();

        public Form1()
        {
            InitializeComponent();
            InitializeUI();
            LoadSampleData();
        }

        private void InitializeUI()
        {
            this.Text = "FBro 多线程注册脚本";
            this.Size = new Size(1200, 800);
            this.StartPosition = FormStartPosition.CenterScreen;

            // 设置状态栏初始状态
            UpdateStatus("就绪");
        }

        private void LoadSampleData()
        {
            // 加载示例注册数据
            for (int i = 1; i <= 10; i++)
            {
                _registrationDataList.Add(new RegistrationData
                {
                    FirstName = $"用户{i}",
                    LastName = $"测试",
                    Email = $"user{i}@example.com",
                    Phone = $"1380000{i:D4}",
                    Username = $"user{i}",
                    Password = "123456",
                    Gender = i % 2 == 0 ? "male" : "female",
                    City = "beijing",
                    Company = $"公司{i}",
                    Bio = $"这是用户{i}的个人简介"
                });
            }

            // 更新数据网格
            if (dataGridViewData != null)
            {
                dataGridViewData.DataSource = _registrationDataList;
            }
        }

        #region 多线程注册逻辑

        private async void btnStartRegistration_Click(object sender, EventArgs e)
        {
            try
            {
                int threadCount = (int)numericUpDownThreads.Value;
                
                if (_registrationDataList.Count == 0)
                {
                    MessageBox.Show("请先添加注册数据！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                // 重置计数器
                _completedCount = 0;
                _successCount = 0;
                _failedCount = 0;

                // 创建取消令牌
                _cancellationTokenSource = new CancellationTokenSource();

                // 更新UI状态
                btnStartRegistration.Enabled = false;
                btnStopRegistration.Enabled = true;
                progressBarTotal.Maximum = _registrationDataList.Count;
                progressBarTotal.Value = 0;

                UpdateStatus($"开始多线程注册，线程数：{threadCount}");

                // 创建注册任务
                _registrationTasks.Clear();
                var dataChunks = SplitDataIntoChunks(_registrationDataList, threadCount);

                for (int i = 0; i < dataChunks.Count; i++)
                {
                    var task = new RegistrationTask
                    {
                        TaskId = i + 1,
                        DataList = dataChunks[i],
                        CancellationToken = _cancellationTokenSource.Token
                    };
                    _registrationTasks.Add(task);
                }

                // 启动所有注册任务
                var tasks = _registrationTasks.Select(task => 
                    Task.Run(() => ExecuteRegistrationTask(task), task.CancellationToken)
                ).ToArray();

                // 等待所有任务完成
                await Task.WhenAll(tasks);

                // 更新最终状态
                UpdateStatus($"注册完成！成功：{_successCount}，失败：{_failedCount}");
                MessageBox.Show($"注册任务完成！\n成功：{_successCount}\n失败：{_failedCount}", 
                    "完成", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (OperationCanceledException)
            {
                UpdateStatus("注册任务已取消");
            }
            catch (Exception ex)
            {
                UpdateStatus($"注册任务出错：{ex.Message}");
                MessageBox.Show($"注册任务出错：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                // 恢复UI状态
                btnStartRegistration.Enabled = true;
                btnStopRegistration.Enabled = false;
            }
        }

        private void btnStopRegistration_Click(object sender, EventArgs e)
        {
            if (_cancellationTokenSource != null)
            {
                _cancellationTokenSource.Cancel();
                UpdateStatus("正在停止注册任务...");
            }
        }

        private List<List<RegistrationData>> SplitDataIntoChunks(List<RegistrationData> data, int chunkCount)
        {
            var chunks = new List<List<RegistrationData>>();
            int chunkSize = (int)Math.Ceiling((double)data.Count / chunkCount);

            for (int i = 0; i < data.Count; i += chunkSize)
            {
                chunks.Add(data.Skip(i).Take(chunkSize).ToList());
            }

            return chunks;
        }

        private async Task ExecuteRegistrationTask(RegistrationTask task)
        {
            string browserUserFlag = $"registration_browser_{task.TaskId}";
            
            try
            {
                // 创建浏览器实例
                await CreateBrowserForTask(browserUserFlag, task.TaskId);

                // 等待浏览器就绪
                await Task.Delay(2000, task.CancellationToken);

                // 处理每个注册数据
                foreach (var data in task.DataList)
                {
                    if (task.CancellationToken.IsCancellationRequested)
                        break;

                    try
                    {
                        await ProcessSingleRegistration(browserUserFlag, data, task.CancellationToken);
                        
                        Interlocked.Increment(ref _successCount);
                        UpdateTaskProgress($"线程{task.TaskId}：{data.Username} 注册成功");
                    }
                    catch (Exception ex)
                    {
                        Interlocked.Increment(ref _failedCount);
                        UpdateTaskProgress($"线程{task.TaskId}：{data.Username} 注册失败 - {ex.Message}");
                    }
                    finally
                    {
                        Interlocked.Increment(ref _completedCount);
                        UpdateProgressBar();
                    }

                    // 任务间延迟
                    await Task.Delay(1000, task.CancellationToken);
                }
            }
            catch (OperationCanceledException)
            {
                UpdateTaskProgress($"线程{task.TaskId}：任务已取消");
            }
            catch (Exception ex)
            {
                UpdateTaskProgress($"线程{task.TaskId}：任务出错 - {ex.Message}");
            }
            finally
            {
                // 关闭浏览器
                await CloseBrowserForTask(browserUserFlag);
            }
        }

        private async Task CreateBrowserForTask(string userFlag, int taskId)
        {
            await Task.Run(() =>
            {
                try
                {
                    // 获取注册页面的完整路径
                    string registrationUrl = Path.Combine(Directory.GetCurrentDirectory(), "registration.html");
                    registrationUrl = "file:///" + registrationUrl.Replace("\\", "/");
                    Console.WriteLine($"注册页面路径：{registrationUrl}");

                    // 创建窗口信息（后台浏览器）
                    FBroSharpWindowsInfo windowInfo = new FBroSharpWindowsInfo
                    {
                        parent_window = IntPtr.Zero,  // 独立窗口
                        x = 100 + (taskId * 50),      // 错开窗口位置
                        y = 100 + (taskId * 50),
                        width = 800,
                        height = 600,
                        window_name = $"注册浏览器 - 线程{taskId}",
                        windowless_rendering_enabled = false
                    };

                    // 创建浏览器设置
                    FBroSharpBrowserSetting settings = new FBroSharpBrowserSetting();

                    // 创建浏览器事件处理器
                    BrowserEvent browserEvent = new BrowserEvent(this);

                    // 创建浏览器
                    bool success = FBroSharpControl.CreatBrowser(
                        registrationUrl,
                        windowInfo,
                        settings,
                        null,  // request_context
                        null,  // extra_info
                        browserEvent,
                        default,  // event_control (struct, use default)
                        userFlag
                    );

                    if (!success)
                    {
                        throw new Exception($"创建浏览器失败 - 线程{taskId}");
                    }

                    UpdateTaskProgress($"线程{taskId}：浏览器创建成功");
                }
                catch (Exception ex)
                {
                    throw new Exception($"创建浏览器出错 - 线程{taskId}: {ex.Message}");
                }
            });
        }

        private async Task ProcessSingleRegistration(string userFlag, RegistrationData data, CancellationToken cancellationToken)
        {
            await Task.Run(async () =>
            {
                try
                {
                    // 获取浏览器实例
                    var browser = FBroSharpBrowserListControl.GetBrowserFromFlag(userFlag);
                    if (browser == null || !browser.IsValid)
                    {
                        throw new Exception("浏览器实例无效");
                    }

                    var frame = browser.GetMainFrame();
                    if (frame == null)
                    {
                        throw new Exception("无法获取主框架");
                    }

                    // 等待页面加载完成
                    await Task.Delay(2000, cancellationToken);

                    // 填写表单字段
                    await FillFormField(frame, "#firstName", data.FirstName, cancellationToken);
                    await FillFormField(frame, "#lastName", data.LastName, cancellationToken);
                    await FillFormField(frame, "#email", data.Email, cancellationToken);
                    await FillFormField(frame, "#phone", data.Phone, cancellationToken);
                    await FillFormField(frame, "#username", data.Username, cancellationToken);
                    await FillFormField(frame, "#password", data.Password, cancellationToken);
                    await FillFormField(frame, "#confirmPassword", data.Password, cancellationToken);

                    // 选择性别
                    if (!string.IsNullOrEmpty(data.Gender))
                    {
                        await SelectOption(frame, "#gender", data.Gender, cancellationToken);
                    }

                    // 选择城市
                    if (!string.IsNullOrEmpty(data.City))
                    {
                        await SelectOption(frame, "#city", data.City, cancellationToken);
                    }

                    // 填写公司
                    if (!string.IsNullOrEmpty(data.Company))
                    {
                        await FillFormField(frame, "#company", data.Company, cancellationToken);
                    }

                    // 填写个人简介
                    if (!string.IsNullOrEmpty(data.Bio))
                    {
                        await FillFormField(frame, "#bio", data.Bio, cancellationToken);
                    }

                    // 勾选服务条款
                    await CheckCheckbox(frame, "#terms", true, cancellationToken);

                    // 提交表单
                    await SubmitForm(frame, "#submitBtn", cancellationToken);

                    // 等待提交完成
                    await Task.Delay(3000, cancellationToken);
                }
                catch (Exception ex)
                {
                    throw new Exception($"处理注册失败: {ex.Message}");
                }
            });
        }

        private async Task FillFormField(IFBroSharpFrame frame, string selector, string value, CancellationToken cancellationToken)
        {
            await Task.Run(() =>
            {
                string script = $@"
                    (function() {{
                        var element = document.querySelector('{selector}');
                        if (element) {{
                            element.value = '{value}';
                            element.dispatchEvent(new Event('input', {{ bubbles: true }}));
                            element.dispatchEvent(new Event('change', {{ bubbles: true }}));
                            return 'success';
                        }}
                        return 'element not found';
                    }})();
                ";

                frame.ExecuteJavaScript(script, "", 0);
            });

            await Task.Delay(100, cancellationToken);
        }

        private async Task SelectOption(IFBroSharpFrame frame, string selector, string value, CancellationToken cancellationToken)
        {
            await Task.Run(() =>
            {
                string script = $@"
                    (function() {{
                        var select = document.querySelector('{selector}');
                        if (select) {{
                            select.value = '{value}';
                            select.dispatchEvent(new Event('change', {{ bubbles: true }}));
                            return 'success';
                        }}
                        return 'element not found';
                    }})();
                ";

                frame.ExecuteJavaScript(script, "", 0);
            });

            await Task.Delay(100, cancellationToken);
        }

        private async Task CheckCheckbox(IFBroSharpFrame frame, string selector, bool check, CancellationToken cancellationToken)
        {
            await Task.Run(() =>
            {
                string script = $@"
                    (function() {{
                        var checkbox = document.querySelector('{selector}');
                        if (checkbox) {{
                            checkbox.checked = {check.ToString().ToLower()};
                            checkbox.dispatchEvent(new Event('change', {{ bubbles: true }}));
                            return 'success';
                        }}
                        return 'element not found';
                    }})();
                ";

                frame.ExecuteJavaScript(script, "", 0);
            });

            await Task.Delay(100, cancellationToken);
        }

        private async Task SubmitForm(IFBroSharpFrame frame, string selector, CancellationToken cancellationToken)
        {
            await Task.Run(() =>
            {
                string script = $@"
                    (function() {{
                        var button = document.querySelector('{selector}');
                        if (button) {{
                            button.click();
                            return 'success';
                        }}
                        return 'element not found';
                    }})();
                ";

                frame.ExecuteJavaScript(script, "", 0);
            });

            await Task.Delay(500, cancellationToken);
        }

        private async Task CloseBrowserForTask(string userFlag)
        {
            await Task.Run(() =>
            {
                try
                {
                    var browser = FBroSharpBrowserListControl.GetBrowserFromFlag(userFlag);
                    if (browser != null && browser.IsValid)
                    {
                        browser.CloseBrowser(true, true);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"关闭浏览器出错: {ex.Message}");
                }
            });
        }

        #endregion

        #region UI更新方法（线程安全）

        public void UpdateStatus(string message)
        {
            if (InvokeRequired)
            {
                Invoke(new Action<string>(UpdateStatus), message);
                return;
            }

            if (lblStatus != null)
            {
                lblStatus.Text = message;
            }
        }

        public void UpdateUrl(string url)
        {
            if (InvokeRequired)
            {
                Invoke(new Action<string>(UpdateUrl), url);
                return;
            }

            // URL更新逻辑（如果需要）
        }

        public void UpdateTitle(string title)
        {
            if (InvokeRequired)
            {
                Invoke(new Action<string>(UpdateTitle), title);
                return;
            }

            // 标题更新逻辑（如果需要）
        }

        public void UpdateNavigationButtons(bool canGoBack, bool canGoForward, bool isLoading)
        {
            if (InvokeRequired)
            {
                Invoke(new Action<bool, bool, bool>(UpdateNavigationButtons), canGoBack, canGoForward, isLoading);
                return;
            }

            // 导航按钮更新逻辑（如果需要）
        }

        private void UpdateTaskProgress(string message)
        {
            if (InvokeRequired)
            {
                Invoke(new Action<string>(UpdateTaskProgress), message);
                return;
            }

            if (listBoxLog != null)
            {
                listBoxLog.Items.Insert(0, $"[{DateTime.Now:HH:mm:ss}] {message}");
                if (listBoxLog.Items.Count > 1000)
                {
                    listBoxLog.Items.RemoveAt(listBoxLog.Items.Count - 1);
                }
            }
        }

        private void UpdateProgressBar()
        {
            if (InvokeRequired)
            {
                Invoke(new Action(UpdateProgressBar));
                return;
            }

            if (progressBarTotal != null)
            {
                progressBarTotal.Value = _completedCount;
            }

            if (lblProgress != null)
            {
                lblProgress.Text = $"进度: {_completedCount}/{_registrationDataList.Count} (成功: {_successCount}, 失败: {_failedCount})";
            }
        }

        #endregion

        #region 数据管理

        private void btnLoadFromExcel_Click(object sender, EventArgs e)
        {
            try
            {
                OpenFileDialog openFileDialog = new OpenFileDialog
                {
                    Filter = "Excel files (*.xlsx;*.xls)|*.xlsx;*.xls|All files (*.*)|*.*",
                    Title = "选择Excel文件"
                };

                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    // 这里可以添加Excel读取逻辑
                    MessageBox.Show("Excel导入功能待实现", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"导入Excel失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void btnClearData_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("确定要清空所有数据吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                _registrationDataList.Clear();
                if (dataGridViewData != null)
                {
                    dataGridViewData.DataSource = null;
                    dataGridViewData.DataSource = _registrationDataList;
                }
            }
        }

        #endregion
    }

    #region 数据模型

    public class RegistrationData
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }
        public string Phone { get; set; }
        public string Username { get; set; }
        public string Password { get; set; }
        public string Gender { get; set; }
        public string City { get; set; }
        public string Company { get; set; }
        public string Bio { get; set; }
    }

    public class RegistrationTask
    {
        public int TaskId { get; set; }
        public List<RegistrationData> DataList { get; set; }
        public CancellationToken CancellationToken { get; set; }
    }

    #endregion
}
